﻿/***********************************************************************************************
 * 
 * ProjectName: WMSSoft.WinKStart
 * 
 * Description: Render Tabpages
 * 
 * Created:     25.11.2012
 * 
 * Author:      matthias wagler - matthias@WMSSoft.de
 * 
 * Copyright:   Copyright 2012 by WMSSoft.de
 * 
 * License:     GPLv3
 * 
 * History:     25.11.2012 - matthias wagler matthias@WMSSoft.de   -   Created
 * 
 **********************************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using WMSSoft.Lib.Basic;
using WMSSoft.Lib.WinKStart;
using WMSSoft.Lib.Enums;
using WMSSoft.Lib.WinKStart.Model.MenuConfig;

namespace WMSSoft.WinKStart.Lib
{
    public class RegionRenderer
    { 
        private System.Windows.Controls.WrapPanel _RegionWrapper = null;
        private System.Windows.Controls.WrapPanel _ButtonBar = null;
        private Dictionary<string, ItemRenderer> _TabPageRenderer = new Dictionary<string, ItemRenderer>();
        private System.Windows.Controls.Image _Selector = null;
        private System.Windows.Controls.Image _SelectPrevious = null;
        private System.Windows.Controls.Image _SelectNext = null;
        private int _LastSelectedTabItem = -1;
        private int _VisibleRegionButtons = 0;
        private int _FirstVisibleRegionButton = 0;

        public event ItemSelectedEventHandler SelectionChanged;        

        public RegionRenderer(System.Windows.Controls.Image Selector = null, 
                               System.Windows.Controls.Image SelectPrevious = null,
                               System.Windows.Controls.Image SelectNext = null)
        {            
            _Selector = Selector;
            _SelectPrevious = SelectPrevious;
            _SelectNext = SelectNext;
        }

        public bool RenderTabpages(System.Windows.Controls.WrapPanel RegionWrapper, System.Windows.Controls.WrapPanel Panel,  System.Windows.Window Parent)
        {
            try
            {
                _ButtonBar = Panel;
                _RegionWrapper = RegionWrapper;

                if (_RegionWrapper != null && _ButtonBar != null && Parent != null)
                {
                    //Delete all existing TabItems
                    _RegionWrapper.Children.Clear();
                    //_RegionWrapper.Items.Clear();
                    _TabPageRenderer.Clear();

                    Dictionary<string, cRegion>.KeyCollection tmpKeys = cMenuConfigReader.TabPages.Keys;
                    foreach (string Item in tmpKeys)
                    {
                        AddRegion(cMenuConfigReader.TabPages[Item]);
                        AddButton(cMenuConfigReader.TabPages[Item]);
                    }

                    Panel.Width = GetNeededButtonsWidth();
                    _VisibleRegionButtons = GetVisibleItems();

                    //Show/ hide Region - Button - Navigation
                    if (_ButtonBar.Children.Count-1 <= _VisibleRegionButtons)
                    {
                        _SelectNext.Visibility = System.Windows.Visibility.Hidden;
                        _SelectPrevious.Visibility = System.Windows.Visibility.Hidden;
                    }
                    else
                    {
                        _SelectNext.Visibility = System.Windows.Visibility.Visible;
                        _SelectPrevious.Visibility = System.Windows.Visibility.Visible;
                    }

                    SetActiveTabItem(0);
                    return true;
                }
                else
                    return false;
            }
            catch (Exception Ex)
            {
                throw new Exception("Error on rendering Regions!", Ex);
            }
        }

        public void UpdateRegion(string RegionName)
        {
            try
            {
                Dictionary<string, cRegion>.KeyCollection RegionKeys = cMenuConfigReader.TabPages.Keys;
                int iKeyIndex = -1;
                foreach (string Item in RegionKeys)
                {
                    iKeyIndex++;
                    if (Item == RegionName) break;
                }

                if (iKeyIndex > -1 && RegionName.Length > 0)
                {
                    ConnectData(cMenuConfigReader.TabPages[RegionName], iKeyIndex);
                }
            }
            catch (Exception Ex)
            {

            }
        }

        public void SelectNextRegion()
        {
            try
            {
                if (_RegionWrapper.Children.Count > 0)
                {
                    if (_LastSelectedTabItem < _RegionWrapper.Children.Count - 1)
                        SetActiveTabItem(_LastSelectedTabItem + 1);
                    else
                        SetActiveTabItem(0);                    
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't select next Region!", Ex);
            }
        }

        public void SelectPreviousRegion()
        {
            try
            {
                if (_RegionWrapper.Children.Count > 0)
                {
                    if (_LastSelectedTabItem > 0)
                        SetActiveTabItem(_LastSelectedTabItem - 1);
                    else
                        SetActiveTabItem(_RegionWrapper.Children.Count - 1);
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't select previous Region!", Ex);
            }
        }

        #region Private Methods

        void AddRegion(cRegion TabPage)
        {
            try
            {
                if (TabPage != null)
                {  
                    System.Windows.Controls.WrapPanel oTabItemContentWrapper = new System.Windows.Controls.WrapPanel();                    
                    //Apply Panel Style
                    cStyleChanger.ApplyStyleToRegion(oTabItemContentWrapper, TabPage.Name);
                    oTabItemContentWrapper.Width = _RegionWrapper.Width;

                    Label otmpBreadCrumb = new Label();
                    otmpBreadCrumb.Width = oTabItemContentWrapper.Width-10;
                    otmpBreadCrumb.Content = "BreadCrumb";

                    cStyleChanger.ApplyStyleToRegionHeader(otmpBreadCrumb, TabPage.Name);

                    System.Windows.Controls.ListBox tmpListBox = new System.Windows.Controls.ListBox();
                    tmpListBox.Background = null; 
                    tmpListBox.BorderBrush = null;
                    tmpListBox.Width = oTabItemContentWrapper.Width;
                    int iBreadCrumHeight = 0;

                    if (TabPage.RendererMethode == eRenderType.Simple) iBreadCrumHeight = (int)otmpBreadCrumb.Height;

                    tmpListBox.Height = _RegionWrapper.Height - iBreadCrumHeight;                    
                    if (TabPage.RendererMethode == eRenderType.Simple && TabPage.CanNavigate == true)
                    {
                        tmpListBox.Tag = otmpBreadCrumb;
                        //only on simple rendering mode is the breadcrumb label on position needed
                        oTabItemContentWrapper.Children.Add(otmpBreadCrumb);
                    }
                    oTabItemContentWrapper.Children.Add(tmpListBox);

                    
                    _RegionWrapper.Children.Add(oTabItemContentWrapper);                   
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't add Region!", Ex);
            }
        }

        void AddButton(cRegion TabPage)
        {
            try
            {
                if (TabPage != null)
                {
                    System.Windows.Controls.StackPanel oPanel = new System.Windows.Controls.StackPanel();
                    oPanel.Height = 80;
                    oPanel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;

                    //Create image
                    System.Windows.Controls.Image oButtonImage = new System.Windows.Controls.Image();
                    oButtonImage.Margin = new System.Windows.Thickness(0.0, 0.0, 0.0, 0.0);
                    oButtonImage.Tag = TabPage.Name;
                    oButtonImage.Width = 80;
                    oButtonImage.Height = 70;
                    oButtonImage.MouseUp += TabPageButton_MouseUp;
                    oButtonImage.MouseMove += TabPageButton_MouseMove;

                    oPanel.Children.Add(oButtonImage);

                    //Create new label under the image
                    System.Windows.Controls.Label tmpLabel = new System.Windows.Controls.Label();
                    tmpLabel.Width = 80;
                    tmpLabel.Content = LanguageStrings.GetText(TabPage.Caption);
                    tmpLabel.Margin = new System.Windows.Thickness(5.0, -25.0, 5.0, 0.0);
                    tmpLabel.MouseUp += TabPageButton_MouseUp;
                    tmpLabel.Tag = TabPage.Name;
                    oPanel.Margin = new System.Windows.Thickness(-4.0, 0.0, 3.0, 0.0);
                    oPanel.Children.Add(tmpLabel);

                    //Apply Style
                    cStyleChanger.ApplyStyleToREgionButton(oPanel, TabPage.Name, true);

                    _ButtonBar.Children.Add(oPanel);

                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't add TabItem - Button!", Ex);
            }
        }

        void ConnectData(cRegion TabPage, int TabPageIndex)
        {
            try
            {
                if (_TabPageRenderer.ContainsKey(TabPage.Name) == false)
                {
                    //ItemRenderer does not exists, create it
                    int itmpListBoxIndex = 0;
                    if (((System.Windows.Controls.WrapPanel)_RegionWrapper.Children[TabPageIndex]).Children.Count > 1)
                    {
                        itmpListBoxIndex = 1;
                    }
                    ItemRenderer renderer = new ItemRenderer(((ListBox)((System.Windows.Controls.WrapPanel)_RegionWrapper.Children[TabPageIndex]).Children[itmpListBoxIndex]),
                                                             null,
                                                             TabPage);
                    //TODO: set settings to control context menu
                    renderer.CanShowContextmenu = TabPage.ShowContextMenu;
                    renderer.CanAddToFavorites = TabPage.CanAddToFavorite;
                    renderer.CanRemoveFavorite = TabPage.CanRemoveFromFavorites;
                    renderer.SelectionChanged += new ItemSelectedEventHandler(RendererSelectionChanged);
                    renderer.AddFavorite += DoAddFavorite;
                    renderer.RemoveFavorite += DoRemoveFavorite;

                    _TabPageRenderer.Add(TabPage.Name, renderer);
                }

                if (_TabPageRenderer.ContainsKey(TabPage.Name) == true)
                {
                    if (TabPage.RendererMethode == eRenderType.Simple)
                    {
                        cStartmenuItem tmpItemData = cMenuConfigReader.DataSources.GetData(TabPage.DataSource, TabPage.Filter);
                        if (tmpItemData != null)
                        {
                            _TabPageRenderer[TabPage.Name].RenderItems(tmpItemData, null, eRenderType.Simple);
                        }
                    }
                    else
                    {
                        _TabPageRenderer[TabPage.Name].RenderGroupItems();
                    }
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't render Region '" + TabPage.Name + "'", Ex);
            }
        }

        void DoRemoveFavorite(string File, int LinkType)
        {
            throw new NotImplementedException();
        }

        void DoAddFavorite(string File, int LinkType)
        {
            try
            {
                switch ((eContentPanelContentType)LinkType)
                {
                    case eContentPanelContentType.Programs:
                        break;
                    case eContentPanelContentType.RecentOpenedDocuments:
                        break;
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't add Favorites!", Ex);
            }
        }

        void RendererSelectionChanged(object Sender, cStartmenuItem Item)
        {
            if (SelectionChanged != null) SelectionChanged(Sender, Item);
        }

        /// <summary>
        /// Returns the to view all Buttons needed width for Buttons host
        /// </summary>
        /// <returns>Calculated width for all Buttons</returns>
        double GetNeededButtonsWidth()
        {
            try
            {
                WMSSoft.Lib.WinKStart.Classes.Styles.cUIElementRegionButtons oRegionButtons = cUserSettingsReader.StyleReader.GetRegionButtonsStyle();
                if (oRegionButtons != null)
                {
                    double iCalculatedRegionButtonsWidth = 0;
                    Dictionary<string, WMSSoft.Lib.WinKStart.Classes.Styles.cUIElementRegionButton>.KeyCollection oButtonKeys = oRegionButtons.Buttons.Keys;
                    foreach (string Key in oButtonKeys)
                    {
                        iCalculatedRegionButtonsWidth += oRegionButtons.Buttons[Key].Width;
                    }
                    return iCalculatedRegionButtonsWidth;
                }
                else throw new Exception("Can't get RegionButtons - Style°!");
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't get Calculated RegionButtons Width!", Ex);
            }
        }

        int GetVisibleItems()
        {
            try
            {
                WMSSoft.Lib.WinKStart.Classes.Styles.cUIElementRegionButtons oRegionButtons = cUserSettingsReader.StyleReader.GetRegionButtonsStyle();
                if (oRegionButtons != null)
                {
                    Dictionary<string, WMSSoft.Lib.WinKStart.Classes.Styles.cUIElementRegionButton>.KeyCollection oButtonKeys = oRegionButtons.Buttons.Keys;
                    double dLeftMargin = 0;
                    int iVisibleItems = 0;

                    foreach (string Key in oButtonKeys)
                    {
                        if (dLeftMargin + oRegionButtons.Buttons[Key].Width < _RegionWrapper.Width)
                        {
                            dLeftMargin += oRegionButtons.Buttons[Key].Width;
                            iVisibleItems++;
                        }
                        else break;
                    }

                    return iVisibleItems;
                }
                else return 0;
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't get Calculate Visible RegionButtons!", Ex);
            }
        }

        void SetActiveTabItem(int Index)
        {
            try
            {
                //set new selected button to image active
                if (((System.Windows.Controls.StackPanel)_ButtonBar.Children[Index]) != null)
                {
                    if (((System.Windows.Controls.StackPanel)_ButtonBar.Children[Index]).Children.Count > 1)
                    {
                        string stmpTabName = "";
                        stmpTabName = (string)((System.Windows.Controls.Image)((System.Windows.Controls.StackPanel)_ButtonBar.Children[Index]).Children[0]).Tag;

                        double iLeftSelectorPos = 0;
                        if (Index > 0)
                        {
                            WMSSoft.Lib.WinKStart.Classes.Styles.cUIElementRegionButton otmpRegionButton = null;
                            for (int iIndexCounter = _FirstVisibleRegionButton; iIndexCounter < Index; iIndexCounter++)
                            {

                                iLeftSelectorPos += ((System.Windows.Controls.Image)((System.Windows.Controls.StackPanel)_ButtonBar.Children[iIndexCounter]).Children[0]).Width;
                            }
                        }
                        if (_Selector != null)
                        {
                            Set_SelectorPosition(iLeftSelectorPos);
                            _Selector.Width = ((System.Windows.Controls.Image)((System.Windows.Controls.StackPanel)_ButtonBar.Children[Index]).Children[0]).Width;
                        }

                        if (_SelectPrevious != null)
                        {
                            _SelectPrevious.MouseUp += _SelectPrevious_MouseUp;
                        }

                        if (_SelectNext != null)
                        {
                            _SelectNext.MouseUp += _SelectNext_MouseUp;
                        }

                        //if (_XMLConfig.DataSources.IsDataSourceUpdated(_XMLConfig.TabPages[stmpTabName].DataSource) == true)
                        {
                            ConnectData(cMenuConfigReader.TabPages[stmpTabName], Index);
                        }

                        Change_VisibleRegion(Index);

                        _LastSelectedTabItem = Index;

                    }
                }

                if (Index < _FirstVisibleRegionButton | Index > _FirstVisibleRegionButton + _VisibleRegionButtons)
                {
                    _Selector.Visibility = System.Windows.Visibility.Hidden;
                }
                else
                    _Selector.Visibility = System.Windows.Visibility.Visible;
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't set active Tab!", Ex);
            }
        }

        void _SelectNext_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            try
            {
                if (_FirstVisibleRegionButton + 1 < (_ButtonBar.Children.Count - _VisibleRegionButtons)) 
                {
                    _FirstVisibleRegionButton++;
                    Set_VisibleRegionButton(_FirstVisibleRegionButton);
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't go to next RegionButton!", Ex);
            }
        }

        void _SelectPrevious_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            try
            {
                if (_FirstVisibleRegionButton > 0)
                {
                    _FirstVisibleRegionButton--;
                    Set_VisibleRegionButton(_FirstVisibleRegionButton);
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't go to previous RegionButton!", Ex);
            }
        }

        void Set_VisibleRegionButton(int Next)
        {
            double iChangeWidth = 0;
            for (int iPanelCounter = 0; iPanelCounter < Next; iPanelCounter++)
            {
                iChangeWidth += ((StackPanel)_ButtonBar.Children[iPanelCounter]).Width;
            }

            _ButtonBar.Margin = new System.Windows.Thickness(0 - iChangeWidth, -80, 0, 0);
            Set_SelectorPosition(_LastSelectedTabItem);
        }

        void Set_SelectorPosition(int Index)
        {
            try
            {
                double dSelectorLeftPost = 0;

                for (int iButtonCounter = _FirstVisibleRegionButton; iButtonCounter < Index; iButtonCounter++)
                {
                    dSelectorLeftPost += ((StackPanel)_ButtonBar.Children[iButtonCounter]).Width;
                }

                if (Index < _FirstVisibleRegionButton | Index > _FirstVisibleRegionButton + _VisibleRegionButtons)
                {
                    _Selector.Visibility = System.Windows.Visibility.Hidden;
                } else 
                    _Selector.Visibility = System.Windows.Visibility.Visible;

                Set_SelectorPosition(dSelectorLeftPost);
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't set Selector Index Position!", Ex);
            }
        }

        void Set_SelectorPosition(double Left)
        {
            try
            {
                if (_Selector != null)
                {
                    _Selector.Margin = new System.Windows.Thickness(Left, _Selector.Margin.Top, _Selector.Margin.Right, _Selector.Margin.Bottom);
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't set Selector Position!", Ex);
            }
        }

        void Change_VisibleRegion(int NewIndex)
        {
            try
            {
                //Hide old region
                if (_LastSelectedTabItem > -1 && _RegionWrapper.Children.Count > 0 && _LastSelectedTabItem < _RegionWrapper.Children.Count)
                {
                    for (int iPanelCounter = 0; iPanelCounter <= _LastSelectedTabItem; iPanelCounter++)
                    {
                        ((WrapPanel)_RegionWrapper.Children[iPanelCounter]).Height = 0;
                        _RegionWrapper.Children[iPanelCounter].Visibility = System.Windows.Visibility.Visible;
                    }
                }

                //show new region
                if (NewIndex > -1 && _RegionWrapper.Children.Count > 0 && NewIndex < _RegionWrapper.Children.Count)
                {
                    ((WrapPanel)_RegionWrapper.Children[NewIndex]).Margin = new System.Windows.Thickness(0.0, 0.0, 0.0, 0.0);
                    ((WrapPanel)_RegionWrapper.Children[NewIndex]).Width = _RegionWrapper.Width;
                    ((WrapPanel)_RegionWrapper.Children[NewIndex]).Height = _RegionWrapper.Height;
                    ((WrapPanel)_RegionWrapper.Children[NewIndex]).Visibility = System.Windows.Visibility.Visible;
                    ((WrapPanel)_RegionWrapper.Children[NewIndex]).Focus();
                }
            }
            catch (Exception Ex)
            {
                throw new Exception("Can' set active Region!", Ex);
            }
        }

        void TabPageButton_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            try
            {
                if (sender.GetType() == typeof(System.Windows.Controls.Image))
                {
                    if (((System.Windows.Controls.Image)sender).Tag != null)
                    {
                        Dictionary<string, cRegion>.KeyCollection tmpKeys = cMenuConfigReader.TabPages.Keys;
                        int iPanelCounter = 0;
                        foreach (string Item in tmpKeys)
                        {

                            if (cMenuConfigReader.TabPages[Item].Name == (string)((System.Windows.Controls.Image)sender).Tag)
                            {
                                SetActiveTabItem(iPanelCounter);
                                break;
                            }
                            iPanelCounter++;
                        }
                    }
                }
                else if (sender.GetType() == typeof(System.Windows.Controls.Label))
                {
                    if (((System.Windows.Controls.Label)sender).Tag != null)
                    {
                        Dictionary<string, cRegion>.KeyCollection tmpKeys = cMenuConfigReader.TabPages.Keys;
                        int iPanelCounter = 0;
                        foreach (string Item in tmpKeys)
                        {

                            if (cMenuConfigReader.TabPages[Item].Name == (string)((System.Windows.Controls.Label)sender).Tag)
                            {
                                SetActiveTabItem(iPanelCounter);
                                break;
                            }
                            iPanelCounter++;
                        }
                    }
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Cant process Select Event!", Ex, true, EMessageTypes.Error);
            }
        }

        void TabPageButton_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            try
            {
                if (cUserSettingsReader.WinKStart.Behavior.SelectEvent == eSelectEvent.MouseMove)
                {
                    if (sender.GetType() == typeof(System.Windows.Controls.Image))
                    {
                        if (((System.Windows.Controls.Image)sender).Tag != null)
                        {
                            Dictionary<string, cRegion>.KeyCollection tmpKeys = cMenuConfigReader.TabPages.Keys;
                            int iPanelCounter = 0;
                            foreach (string Item in tmpKeys)
                            {

                                if (cMenuConfigReader.TabPages[Item].Name == (string)((System.Windows.Controls.Image)sender).Tag)
                                {
                                    SetActiveTabItem(iPanelCounter );
                                    break;
                                }
                                iPanelCounter++;
                            }
                        }
                    }
                    else if (sender.GetType() == typeof(System.Windows.Controls.Label))
                    {
                        if (((System.Windows.Controls.Label)sender).Tag != null)
                        {
                            Dictionary<string, cRegion>.KeyCollection tmpKeys = cMenuConfigReader.TabPages.Keys;
                            int iPanelCounter = 0;
                            foreach (string Item in tmpKeys)
                            {

                                if (cMenuConfigReader.TabPages[Item].Name == (string)((System.Windows.Controls.Label)sender).Tag)
                                {
                                    SetActiveTabItem(iPanelCounter );
                                    break;
                                }
                                iPanelCounter++;
                            }
                        }
                    }
                }
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Cant process Select Event!", Ex, true, EMessageTypes.Error);
            }
        }
        #endregion
    }
}
